/**
 * 
 */
package com.wolfpire.system.dao.impl;

import java.util.ArrayList;
import java.util.List;

import org.apache.commons.lang3.StringUtils;
import org.hibernate.Criteria;
import org.hibernate.SQLQuery;
import org.hibernate.criterion.Criterion;
import org.hibernate.criterion.MatchMode;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Restrictions;
import org.springframework.stereotype.Repository;

import com.wolfpire.system.common.Constants;
import com.wolfpire.system.common.EasyuiPage;
import com.wolfpire.system.common.Page;
import com.wolfpire.system.common.base.dao.impl.BaseHibernateDao;
import com.wolfpire.system.dao.AuthorityDao;
import com.wolfpire.system.model.Authority;

/**
 * @author lihd
 *
 */

@Repository("authorityDao")
public class AuthorityDaoImpl extends BaseHibernateDao<Authority, Long> implements AuthorityDao {
	
	@SuppressWarnings("unchecked")
	
	public List<Authority> list(Authority authority) {
//		Criteria criteria = createCriteria(this.createFilter(authority));
		Criteria criteria = createCriteria(this.createFilter(authority, "tree", false));
		criteria.addOrder(Order.asc("seq"));
		return criteria.list();
	}

	
	public Page<Authority> findAuthoritys(EasyuiPage<Authority> page, Authority filterAuthority) {
//		Criterion[] criterions = this.createFilter(filterAuthority);
		Criterion[] criterions = this.createFilter(filterAuthority, null, true);
		int totalCount = this.findIntByCriteria(criterions);
		page.setTotalCount(totalCount);
		if (0 < totalCount) {
			Criteria c = createCriteria(criterions);
			c = setPageParameter(c, page);
			c.addOrder(Order.asc("seq"));
			@SuppressWarnings("unchecked")
			List<Authority> authoritys = c.list();
			page.setDataList(authoritys);
		}
		return page;
	}
	
	
	public boolean isUniqueName(Authority authority) {
		Criteria criteria = null;
		List<Criterion> criterions = new ArrayList<Criterion>();
		criterions.add(Restrictions.eq("name", authority.getName()));
		criterions.add(Restrictions.eq("delFlag", Constants.NORMAL_FLAG));
		Long parentId = authority.getParentId();
		if (null != parentId) {
			criterions.add(Restrictions.eq("parentId", parentId));
		}
		Long id = authority.getId();
		if (null != id) {
			criterions.add(Restrictions.ne("id", id));
		}
		criteria = createCriteria(criterions.toArray(new Criterion[criterions.size()]));
		@SuppressWarnings("unchecked")
		List<Authority> authoritys = criteria.list();
		if (null != id) {
			return authoritys == null || authoritys.size() < 2;
		} else {
			return authoritys == null || authoritys.size() < 1; 
		}
	}
	
	/**
	 * 构造过滤条件
	 * @param filterAuthority
	 * @return
	 */
	private Criterion[] createFilter(Authority filterAuthority, String type, boolean cascadeParentId) {
		if (null == filterAuthority) {
			return null;
		}
		List<Criterion> criterions = new ArrayList<Criterion>();
		if (null != filterAuthority.getId()) {
			criterions.add(Restrictions.eq("id", filterAuthority.getId()));
		}
		/*if (null != filterAuthority.getParentId()) {
			criterions.add(Restrictions.eq("parentId", filterAuthority.getParentId()));
		} else {
			criterions.add(Restrictions.isNull("parentId"));
		}*/
		
		if (null != filterAuthority.getParentId()) {
			criterions.add(Restrictions.eq("parentId", filterAuthority.getParentId()));
		} else {
			if ("tree".equals(type)) {
				criterions.add(Restrictions.isNull("parentId"));
			}
		}
		if (!StringUtils.isBlank(filterAuthority.getName())) {
			criterions.add(Restrictions.like("name", filterAuthority.getName(), MatchMode.ANYWHERE));
		}
		if (null != filterAuthority.getDelFlag()) {
			criterions.add(Restrictions.eq("delFlag", filterAuthority.getDelFlag()));
		}
		return criterions.toArray(new Criterion[criterions.size()]);
	}

	@SuppressWarnings("unchecked")
	
	public List<Authority> findByUserId(Long userId) {
		StringBuffer sql = new StringBuffer();
		sql.append("SELECT a.* ")
			.append(" FROM t_sm_user u, t_sm_role r, t_sm_user_role ur, t_sm_authority a, t_sm_role_authority ra ")
			.append(" WHERE u.id = ur.user_id AND ur.role_id = r.id AND r.id = ra.role_id AND ra.authority_id = a.id ")
			.append(" AND u.del_flag=1 AND r.del_flag=1 AND a.del_flag=1 ")
			.append(" AND u.id=? ")
			.append(" ORDER BY a.seq ");
		SQLQuery query = (SQLQuery) this.createSqlQuery(sql.toString(), new Object[]{userId});
		query.addEntity(Authority.class);
		return query.list();
	}

	@SuppressWarnings({ "rawtypes", "unchecked" })
	
	public List<Authority> getCatalogAndMenuTypeByUserId(Long userId) {
		StringBuffer sql = new StringBuffer();
		sql.append("SELECT a.* ")
				.append(" FROM t_sm_user u, t_sm_role r, t_sm_user_role ur, t_sm_authority a, t_sm_role_authority ra ")
				.append(" WHERE u.id = ur.user_id AND ur.role_id = r.id AND r.id = ra.role_id AND ra.authority_id = a.id ")
				.append(" AND u.del_flag=1 AND r.del_flag=1 AND a.del_flag=1 And a.type in (:type) ")
				.append(" AND u.id=:id ")
				.append(" ORDER BY a.seq ");
		ArrayList<String> propertyNames = new ArrayList<String>();
		propertyNames.add("type");
		propertyNames.add("id");
		ArrayList propertyValues = new ArrayList();
		ArrayList<Integer> types = new ArrayList<Integer>();
		types.add(Authority.TYPE_CATALOG);
		types.add(Authority.TYPE_MENU);
		propertyValues.add(types);
		propertyValues.add(userId);
		SQLQuery query = (SQLQuery) this.createSqlQuery(sql.toString(), propertyNames, propertyValues);
		query.addEntity(Authority.class);
		return query.list();
		
		
		
		
	}

	@SuppressWarnings("unchecked")
	
	public List<Authority> listTree(Authority authority) {
		Criteria criteria = createCriteria(
				Restrictions.eq("delFlag", Constants.NORMAL_FLAG)
				);
		criteria.addOrder(Order.asc("seq"));
		return criteria.list();
	}

}